"use strict";

module.exports = core;

// require: .js, .json, .node
// .js -> module.exports/exports
// .json -> JSON.parse
// .node -> C/C++编译的二进制文件 process.dlopen(module, path.toModule)
// any -> .js
// a.baocuo
// b.hello world
// const file = require("../file.txt");
// file();
const path = require("path");
const semver = require("semver"); // 比对node版本
const colors = require("colors"); // 给输入的提示加上颜色
const userHome = require("os").homedir(); // 判断用户主目录  user-home插件已经弃用
const pathExists = require("path-exists"); // 判断文件是否存在
const commander = require("commander"); // 命令行解析

// const init = require("@akimixu-cli-dev/init");
const exec = require("@akimixu-cli-dev/exec");
const log = require("@akimixu-cli-dev/log");

const pkg = require("../package.json");
// const constant = require("./const");

const program = new commander.Command();
async function core() {
  try {
    await prepare(); // 准备阶段
    registerCommand(); // 注册命令
  } catch (e) {
    //捕获报错信息，不将报错的栈列出来
    log.error(e.message);
    // 只希望在debug的时候才打印报错process.env.LOG_LEVEL === "verbose" / program.debug
    if (program.opts().debug) {
      console.log(e);
    }
  }
}

// 准备流程
async function prepare() {
  checkPkgVersion(); // 检查版本号
  checkRoot(); // 检查root账户
  checkUserHome(); // 检查用户主目录
  // checkInputArgs(); //如果不修改log.level，要想执行log.verbose，这个初始化要在下一行引入log之前
  // log.verbose("debug", "test debug log");
  checkEnv(); // 检查环境变量
  await checkGlobalUpdate(); // 检查全局更新
}

// 检查版本号
function checkPkgVersion() {
  log.notice("cli", pkg.version);
}

// 获取自身权限值，0是超级管理员
function checkRoot() {
  const rootCheck = require("root-check"); // 判断是否是管理员的插件，1.0.0版本是require,2.0.0版本是import,nodejs不能使用import，不必为了这个加入babel转义
  rootCheck();
  //console.log(process.getuid()); // 可以使用sodu akimixu-cli-dev查看现在权限，哪怕是sudo现在也是1000的权限，root-check会自动降级
}

// 判断用户主目录
function checkUserHome() {
  if (!userHome || !pathExists(userHome)) {
    throw new Error(colors.red("用户主目录不存在!"));
  }
}

// 检查入参
// function checkInputArgs() {
//   const minimist = require("minimist");
//   args = minimist(process.argv.slice(2));
//   checkArgs();
// }
// function checkArgs() {
//   if (args.debug) {
//     process.env.LOG_LEVEL = "verbose";
//   } else {
//     process.env.LOG_LEVEL = "info";
//   }
//   log.level = process.env.LOG_LEVEL;
// }

// 检查环境变量
function checkEnv() {
  const dotenv = require("dotenv");
  const dotenvPath = path.resolve(userHome, ".env"); //如果有更多的值可以直接配置在.env文件里面
  if (pathExists(dotenvPath)) {
    dotenv.config({ path: dotenvPath });
  }
  createDefaultConfig();
}
// 如果没有环境变量，就创建环境变量
function createDefaultConfig() {
  const cliConfig = {
    home: userHome,
  };
  if (process.env.CLI_HOME) {
    cliConfig["cliHome"] = path.join(userHome, process.env.CLI_HOME);
  } else {
    cliConfig["cliHome"] = path.join(userHome, process.env.DEFAULT_CLI_HOME);
  }

  process.env.CLI_HOME_PATH = cliConfig.cliHome;
}

// 检查是否需要全局更新
async function checkGlobalUpdate() {
  // 1.获取当前的版本号和模块名
  const currentVersion = pkg.version;
  const npmName = pkg.name;
  // 2.调用npm API， 获取所有版本号
  const { getNpmSemverVersion } = require("@akimixu-cli-dev/get-npm-info");
  // const lastversions = await getNpmSemverVersion(
  //   currentVersion,
  //   "@imooc-cli/core"
  // ); //测试用
  const lastversions = await getNpmSemverVersion(currentVersion, npmName); //自己的版本
  if (lastversions && semver.gt(lastversions, currentVersion)) {
    log.warn(
      colors.yellow(`请手动更新${npmName},当前版本：${currentVersion},最新版本：${lastversions}
    更新命令：npm install -g ${npmName}`)
    );
  }

  // 3.提取所有版本号，比对那些版本号是大于当前版本号
  // 4.获取最新的版本号，提示用户更新到该版本
}

// 命令注册
function registerCommand() {
  //
  program
    .name(Object.keys(pkg.bin)[0]) // 获取package.json中的bin字段
    .usage("<command> [options]") // 用法
    .version(pkg.version) // 版本号
    .option("-d --debug", "是否开启调试模式", false) // debug模式
    .option("-tp, --targetPath <targetPath>", "是否指定本地调试文件路径", ""); // 指定本地调试文件路径

  //
  program
    .command("init [projectName]")
    .option("-f --force", "是否强制初始化项目")
    .action(exec);

  // 开启debug模式
  program.on("option:debug", function () {
    if (program.opts().debug) {
      process.env.LOG_LEVEL = "verbose";
    } else {
      process.env.LOG_LEVEL = "info";
    }
    log.level = process.env.LOG_LEVEL;
    log.verbose("test verbose");
  });

  // 指定 targetPath
  program.on("option:targetPath", function () {
    process.env.CLI_TARGET_PATH = program.opts().targetPath;
  });
  // 未知命令的监听
  program.on("command:*", function (obj) {
    const availableCommands = program.commands.map((cmd) => cmd.name()); //获取所有的命令
    console.log(colors.red("未知的命令：" + obj[0]));
    if (availableCommands.length > 0) {
      console.log(colors.red("可用命令：" + availableCommands.join(",")));
    }
  });

  program.parse(process.argv); // 先解析命令行参数，再执行下面的代码
  if (program.args && program.args.length < 1) {
    program.outputHelp(); //输出帮助信息
  }
}
